package com.feisuanyz.service.impl;

import com.feisuanyz.dao.MealMapper;
import com.feisuanyz.dao.MealSelectionMapper;
import com.feisuanyz.pojo.domain.MealDO;
import com.feisuanyz.pojo.dto.MealDTO;
import com.feisuanyz.pojo.query.MealQuery;
import com.feisuanyz.pojo.query.MealSelectionQuery;
import com.feisuanyz.pojo.vo.MealSelectionVO;
import com.feisuanyz.pojo.vo.PageResult;
import com.feisuanyz.service.MealService;
import java.lang.Boolean;
import java.lang.Override;
import java.util.List;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.feisuanyz.exception.BusinessException;
import java.util.Random;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import java.util.Map;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.feisuanyz.pojo.domain.MealSelectionDO;
import com.feisuanyz.constant.ResultCodeConstant;
import lombok.Data;
import java.util.Date;

/**
 * 菜单管理的实现
 *
 * @author Chenke Zhao
 * @date 2025-03-06 10:18:05
 */
@Service
public class MealServiceImpl implements MealService {

    @Autowired
    private MealMapper mealMapper;

    @Autowired
    private MealSelectionMapper mealSelectionMapper;

    @Autowired
    private RedissonClient redissonClient;

    @Override
    public Boolean addMeal(MealDTO mealDTO) {
        MealDO mealDO = new MealDO();
        mealDO.setMealName(mealDTO.getMealName());
        mealDO.setMealType(mealDTO.getMealType());
        mealDO.setUserId(mealDTO.getUserId());
        mealDO.setCreateBy("admin");
        mealDO.setCreateTime(new Date());
        int result = mealMapper.insert(mealDO);
        if (result > 0) {
            return true;
        } else {
            throw new BusinessException(ResultCodeConstant.CODE_000001, ResultCodeConstant.CODE_000001_MSG);
        }
    }

    @Override
    public Boolean deleteMeal(MealDTO mealDTO) {
        QueryWrapper<MealDO> wrapper = Wrappers.query();
        wrapper.eq("id", mealDTO.getMealId()).eq("user_id", mealDTO.getUserId());
        int result = mealMapper.delete(wrapper);
        if (result > 0) {
            return true;
        } else {
            throw new BusinessException(ResultCodeConstant.CODE_000001, ResultCodeConstant.CODE_000001_MSG);
        }
    }

    @Override
    public Boolean updateMeal(MealDTO mealDTO) {
        MealDO mealDO = new MealDO();
        mealDO.setId(mealDTO.getMealId());
        mealDO.setMealName(mealDTO.getMealName());
        mealDO.setMealType(mealDTO.getMealType());
        mealDO.setUserId(mealDTO.getUserId());
        mealDO.setUpdateBy("admin");
        mealDO.setUpdateTime(new Date());
        int result = mealMapper.updateById(mealDO);
        if (result > 0) {
            return true;
        } else {
            throw new BusinessException(ResultCodeConstant.CODE_000001, ResultCodeConstant.CODE_000001_MSG);
        }
    }

    @Override
    public PageResult<MealDO> getUserMeals(MealQuery mealQuery) {
        QueryWrapper<MealDO> wrapper = Wrappers.query();
        wrapper.eq("user_id", mealQuery.getUserId());
        if (mealQuery.getMealType() != null) {
            wrapper.eq("meal_type", mealQuery.getMealType());
        }
        IPage<MealDO> page = new Page<>(mealQuery.getPageIndex(), mealQuery.getPageSize());
        IPage<MealDO> mealPage = mealMapper.selectPage(page, wrapper);
        PageResult<MealDO> pageResult = new PageResult<>(mealPage);
        return pageResult;
    }

    @Override
    public MealDO randomSelect(MealSelectionQuery mealSelectionQuery) {
        try {
            // 获取当前用户对应的食物类型的所有食物
            QueryWrapper<MealDO> mealWrapper = Wrappers.query(new MealDO()).eq("user_id", mealSelectionQuery.getUserId()).eq("meal_type", mealSelectionQuery.getMealType());
            List<MealDO> allMeals = mealMapper.selectList(mealWrapper);
            // 获取当前用户最近3天内选择过的食物
            Date threeDaysAgo = new Date(System.currentTimeMillis() - 3 * 24 * 60 * 60 * 1000);
            QueryWrapper<MealSelectionDO> selectionWrapper = Wrappers.query(new MealSelectionDO()).eq("user_id", mealSelectionQuery.getUserId()).ge("selection_time", threeDaysAgo);
            List<MealSelectionDO> recentSelections = mealSelectionMapper.selectList(selectionWrapper);
            // 将获取到的最近3天内选择过的食物从所有食物中移除
            List<Integer> selectedMealIds = recentSelections.stream().map(MealSelectionDO::getMealId).collect(Collectors.toList());
            List<MealDO> availableMeals = allMeals.stream().filter(meal -> !selectedMealIds.contains(meal.getId())).collect(Collectors.toList());
            // 从剩余的食物中随机选择一个食物
            if (availableMeals.isEmpty()) {
                throw new BusinessException(ResultCodeConstant.CODE_000001, ResultCodeConstant.CODE_000001_MSG);
            }
            Random random = new Random();
            MealDO selectedMeal = availableMeals.get(random.nextInt(availableMeals.size()));
            // 将随机选择的食物记录到meal_selections表中
            MealSelectionDO mealSelectionDO = new MealSelectionDO();
            mealSelectionDO.setUserId(mealSelectionQuery.getUserId());
            mealSelectionDO.setMealId(selectedMeal.getId());
            mealSelectionDO.setCreateBy("system");
            mealSelectionMapper.insert(mealSelectionDO);
            return selectedMeal;
        } catch (Exception e) {
            throw new BusinessException(ResultCodeConstant.CODE_000001, ResultCodeConstant.CODE_000001_MSG);
        }
    }

    @Override
    public List<MealSelectionVO> getSelectionHistory(MealSelectionQuery mealSelectionQuery) {
        try {
            // 获取当前用户的所有选择记录
            QueryWrapper<MealSelectionDO> selectionWrapper = Wrappers.query(new MealSelectionDO()).eq("user_id", mealSelectionQuery.getUserId());
            List<MealSelectionDO> selectionDOs = mealSelectionMapper.selectList(selectionWrapper);

            // 获取对应的食物信息
            List<Integer> mealIds = selectionDOs.stream().map(MealSelectionDO::getMealId).collect(Collectors.toList());
            List<MealDO> meals = mealMapper.selectBatchIds(mealIds);

            // 将选择记录和食物信息封装到渲染实体类中
            List<MealSelectionVO> selectionVOs = selectionDOs.stream().map(selectionDO -> {
                MealSelectionVO vo = new MealSelectionVO();
                vo.setId(selectionDO.getId());
                vo.setUserId(selectionDO.getUserId());
                vo.setMealId(selectionDO.getMealId());
                vo.setSelectionTime(selectionDO.getSelectionTime());

                MealDO meal = meals.stream()
                        .filter(m -> m.getId().equals(selectionDO.getMealId()))
                        .findFirst()
                        .orElse(null);

                vo.setMealName(meal != null ? meal.getMealName() : null);
                vo.setMealType(meal != null ? meal.getMealType() : null);

                return vo; // 添加返回值
            }).collect(Collectors.toList());

            return selectionVOs;
        } catch (Exception e) {
            throw new BusinessException(ResultCodeConstant.CODE_000001, ResultCodeConstant.CODE_000001_MSG);
        }
    }
}
